﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using RA.UI.Views;
using System.Windows.Controls.Primitives;
using RA.CompileServices;
using RA.Common;
using RA.UI.ViewModel;
using RA.UI.Messages;
using GalaSoft.MvvmLight.Messaging;
using RA.Services;
using GalaSoft.MvvmLight;
using System.ComponentModel;


namespace RA.UI
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow
    {
        public PanelToolsView A;
        public AgentsManagerView B;
        public MethodsManagerView C;
        object _selectedItem;
        object _firstSelectedItem;
        object _secondSelectedItem;
        public Boolean IsAddConnection = false;
        public Boolean IsAddFirstConnect = false;

        public List<Agent> saveListAgents = new List<Agent>(); // список агентов
        public List<interaction> saveInteractions = new List<interaction>(); // список связей агентоа

        private List<Object> VisualElements = new List<object>();

        public MainWindow()
        {
            InitializeComponent();
            A = outlookBar.Sections[4].Content as PanelToolsView;
            B = outlookBar.Sections[3].Content as AgentsManagerView;
            C = outlookBar.Sections[2].Content as MethodsManagerView;
            if (A != null)
            {
                A.btnAddAgent.Click +=btnAddAgent_Click;
                A.btnAddConnect.Click += btnAddConnect_Click;
                A.btnGen.Click += btnGen_Click;
                A.btnSave.Click += btnSave_Click;
            }
            PreviewKeyDown += MainWindow_PreviewKeyDown;
        }

        void btnAddAgent_Click(object sender, RoutedEventArgs e)
        {
            if (A.lbTypeAgents.SelectedItems == null)
                return;

            var selectedItem = A.lbTypeAgents.SelectedItem as ListBoxItem;
            if (selectedItem == null) return;
            var name = selectedItem.Content.ToString();
            if (name.Equals("Агент поиска шаблонов") || name.Equals("Агент поиска подстрок"))
            {
                return;
            }

            var button = new AgentView {Width = 220, Height = 40, label = {Content = name}};
            Canvas.SetLeft(button, 0);
            Canvas.SetTop(button, 0);
            Canvas.SetLeft(button.AgentContent, 0);
            Canvas.SetTop(button.AgentContent, 0);
            canvas.Children.Add(button);
            button.AgentContent.DragDelta +=AgentContent_DragDelta;
            button.AgentContent.DragCompleted +=AgentContent_DragCompleted;
            button.AgentContent.MouseLeftButtonDown += button_MouseDown;
            VisualElements.Add(button);

            // Модификация
            // Добавляем агент в систему
            Agent newAgent = new Agent();
            newAgent.agentName = name;
            saveListAgents.Add(newAgent);
        }

        void btnAddConnect_Click(object sender, RoutedEventArgs e)
        {
            //if (A.lbTypeConnect.SelectedItems == null)
            //    return;
            IsAddConnection = true;

            // Модификация
            // Добавляем связь в систему
            interaction ite = new interaction();
            saveInteractions.Add(ite);
        }


        void AgentContent_DragDelta(object sender, DragDeltaEventArgs e)
        {
            var myThumb = (Thumb)sender;
            var res = (UserControl)myThumb.DataContext;

            var topChange = Canvas.GetTop(res) + res.ActualHeight + e.VerticalChange;
            var leftChange = Canvas.GetLeft(res) + res.ActualWidth + e.HorizontalChange;

            if ((topChange <= canvas.ActualHeight) && (topChange >= res.ActualHeight))
            {
                Canvas.SetTop(res, Canvas.GetTop(res) + e.VerticalChange);
                Canvas.SetTop(myThumb, Canvas.GetTop(myThumb) + e.VerticalChange);
                MoveRelation(res as AgentView);
            }
            if ((leftChange <= canvas.ActualWidth) && (leftChange >= res.ActualWidth))
            {
                Canvas.SetLeft(res, Canvas.GetLeft(res) + e.HorizontalChange);
                Canvas.SetLeft(myThumb, Canvas.GetLeft(myThumb) + e.HorizontalChange);
                MoveRelation(res as AgentView);
            }

        }

        void MoveRelation(AgentView control)
        {
            var relationAgents = new List<AgentView>();
            foreach (var child in canvas.Children)
            {
                if (child is AgentView && (child as AgentView) != control)
                {
                    foreach (var conection in control.conections)
                    {
                        if ((child as AgentView).conections.Contains(conection))
                        {
                            if (!relationAgents.Contains((child as AgentView)))
                            {
                                relationAgents.Add((child as AgentView));
                                break;
                            }
                        }
                    }
                }
            }
            if (relationAgents.Count > 0)
            {
                foreach (var agent in relationAgents)
                {
                    RelationUpdate(control, agent);   
                }
            }
        }

        void RelationUpdate(AgentView control1, AgentView control2)
        {
            foreach (var connect in control1.conections)
            {
                if (control2.conections.Contains(connect))
                {
                    canvas.Children.Remove(connect as UIElement);
                    control1.conections.Remove(connect);
                    control2.conections.Remove(connect);
                    var line = new Line
                        {
                            X1 = Canvas.GetLeft(control1) + control1.ActualWidth/2,
                            Y1 = Canvas.GetTop(control1) + control1.ActualHeight/2,
                            X2 = Canvas.GetLeft(control2) + control2.ActualWidth/2,
                            Y2 = Canvas.GetTop(control2) + control2.ActualHeight/2,
                            Stroke = Brushes.Black,
                            StrokeThickness = 2
                        };
                    canvas.Children.Insert(0, line);
                    control1.conections.Add(line);
                    control2.conections.Add(line);

                    return;
                }
            }
        }

        void AgentContent_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            
            _selectedItem = sender;
            loadAgent();

            if (IsAddConnection)
            {
                // Добавление связи
                if (IsAddFirstConnect)
                {
                    _secondSelectedItem = _selectedItem;
                    //Прорисовка линии
                    var line = new Line();
                    var firstAgent = ((_firstSelectedItem as Thumb).DataContext as AgentView);
                    var secondAgent = ((_secondSelectedItem as Thumb).DataContext as AgentView);

                    if (firstAgent == secondAgent)
                    {
                        firstAgent = null;
                        secondAgent = null;
                        IsAddConnection = false;
                        IsAddFirstConnect = false;
                        return;
                    }
                    if (firstAgent != null)
                    {
                        foreach (var firstConnect in firstAgent.conections)
                        {
                            if (secondAgent != null && secondAgent.conections.Contains(firstConnect))
                            {
                                firstAgent = null;
                                secondAgent = null;
                                IsAddConnection = false;
                                IsAddFirstConnect = false;
                                return;
                            }
                        }

                        line.X1 = Canvas.GetLeft(firstAgent) + firstAgent.ActualWidth/2;
                        line.Y1 = Canvas.GetTop(firstAgent) + firstAgent.ActualHeight / 2;
                    }
                    line.X2 = Canvas.GetLeft(secondAgent) + secondAgent.ActualWidth / 2; 
                    line.Y2 = Canvas.GetTop(secondAgent) + secondAgent.ActualHeight / 2;
                    line.Stroke = Brushes.Black;
                    line.StrokeThickness = 2;
                    canvas.Children.Insert(0,line);
                    if (firstAgent != null) firstAgent.conections.Add(line);
                    secondAgent.conections.Add(line);

                    IsAddConnection = false;
                    IsAddFirstConnect = false;
                    firstAgent = null;
                    secondAgent = null;
                   
                    // Получение агент получателя
                    saveInteractions[saveInteractions.Count - 1].receiver = ((_secondSelectedItem as Thumb).DataContext as AgentView).label.Content.ToString();
                    return;
                }
                //Выделение первого объкта для связи
                _firstSelectedItem = _selectedItem;

                IsAddFirstConnect = true;
                // Получение агент отправителя
                int k = saveInteractions.Count - 1;
                saveInteractions[k].sender = ((_firstSelectedItem as Thumb).DataContext as AgentView).label.Content.ToString();

            }

        }

        private void outlookBar_SelectedSectionChanged(object sender, RoutedPropertyChangedEventArgs<Odyssey.Controls.OutlookSection> e)
        {
            if (canvas == null) return;
            if (outlookBar.SelectedSectionIndex == 4)
            {
                scrollViewerCanvas.Visibility = Visibility.Visible;
                imageDisplayView1.Visibility = Visibility.Hidden;
            }
            else
            {
                scrollViewerCanvas.Visibility = Visibility.Hidden;
                imageDisplayView1.Visibility = Visibility.Visible;
            }

        }

        private void button_MouseDown(object sender, MouseButtonEventArgs e)
        {
            _selectedItem = sender;
            
        }

        //public void BroadCastSettingsChangedToDefaults()
        //{
        //    Messenger.Default.Send(new SettingsChangedMessage(RA.Common.Settings.Current));
        //    SettingsViewModel Settings = new SettingsViewModel(RA.Common.Settings.Current);
        //    RaisePropertyChanged(() => Settings);
        //}

        private void loadAgent()
        {
            var typeAgent = ((_selectedItem as Thumb).DataContext as AgentView).label.Content;

            for (var i = 0; i < saveListAgents.Count; i++)
            {
                if (saveListAgents[i].agentView == _selectedItem)
                {
                    if (typeAgent.Equals("Агент поиска шаблонов"))
                    {
                        B.tbAgentName.Text = saveListAgents[i].agentName;
                        CompileService cs = new CompileService();
                        String fileName = AppDomain.CurrentDomain.BaseDirectory + "Agents\\" + saveListAgents[i].agentName + ".dll";
                        Messenger.Default.Send(new ChangeAgentMessage(cs.GetAgent(fileName)));
                        
                    }
                    else
                    {
                        B.tbAgentName2.Text = saveListAgents[i].agentName;
                        B.tbKeys.Text = saveListAgents[i].keys;
                        B.tbXPath.Text = saveListAgents[i].xPath;
                        B.tbTemplatesURL.Text = saveListAgents[i].templateUrl;
                    }

                }
            }
        }

        private void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (outlookBar.SelectedSectionIndex == 4)
            {
                if (e.Key == Key.Delete)
                {   // удалить связи
                    if (_selectedItem != null)
                    {
                        if ((_selectedItem is Thumb))
                        {
                            var element = ((_selectedItem as Thumb).DataContext as AgentView);

                            for (int i = 0; i < canvas.Children.Count; i++)
                            {
                                if (canvas.Children[i] is AgentView && (canvas.Children[i] as AgentView) != element)
                                {
                                    for (var j = 0; j < element.conections.Count; j++) 
                                    {
                                        if ((canvas.Children[i] as AgentView).conections.Contains(element.conections[j]))
                                        {
                                            (canvas.Children[i] as AgentView).conections.Remove(element.conections[j]);
                                            canvas.Children.Remove(element.conections[j] as UIElement);
                                            element.conections.Remove(element.conections[j]);
                                            i = -1;
                                            break;
                                        }
                                    }
                                }
                            }

                            VisualElements.Remove(element);
                            canvas.Children.Remove(element);
                        }
                    }
                }
                else if (e.Key == Key.Escape)
                {
                    _selectedItem = null;
                    IsAddConnection = false;
                    IsAddFirstConnect = false;
                }
            }
        }
        /// <summary>
        /// Генерация кода агентов
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnGen_Click(object sender, RoutedEventArgs e)
        {
            CompileService _compileService = new CompileService();
           // var name = "agent";

           // _compileService.CompileImageRecognitionAgent(Settings.Default, name);

            // Генерация всех агентов в системе
            for (int i = 0; i < saveListAgents.Count; i++)
            {
                _compileService.CompileImageRecognitionAgent(Settings.Default, saveListAgents[i].agentName + i.ToString());
            }

            // Генерация всех связей

            for (int i = 0; i < saveInteractions.Count; i++)
            {
                _compileService.ComplierInteraction("Связь № " + i.ToString());
            }
        }

        /// <summary>
        /// Сохранение агента
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnSave_Click(object sender, RoutedEventArgs e)
        {
            CompileService _compileService = new CompileService();

            if(_selectedItem!=null)
            {
                Agent currentAgent = new Agent();
                currentAgent.agentView = _selectedItem;
                var typeAgent = ((_selectedItem as Thumb).DataContext as AgentView).label.Content;
                if (typeAgent.Equals("Агент поиска шаблонов"))
                {
                    Settings currentSettings = new Settings()
                        {
                            AdaptiveThresholdBlockSize = Settings.Current.AdaptiveThresholdBlockSize,
                            AdaptiveThresholdParameter = Settings.Current.AdaptiveThresholdParameter,
                            AddCanny = Settings.Current.AddCanny,
                            Blur = Settings.Current.Blur,
                            CannyThreshold = Settings.Current.CannyThreshold,
                            EqualizeHist = Settings.Current.EqualizeHist,
                            FilterContoursBySize = Settings.Current.FilterContoursBySize,
                            Method = Settings.Current.Method,
                            MinContourArea = Settings.Current.MinContourArea,
                            MinContourLength = Settings.Current.MinContourLength,
                            MinFormFactor = Settings.Current.MinFormFactor,
                            NoiseFilter = Settings.Current.NoiseFilter,
                            OnlyFindContours = Settings.Current.OnlyFindContours
                        };                    
                    currentAgent.agentName = B.tbAgentName.Text;
                    currentAgent.imageAgentSettings = currentSettings;
                    _compileService.CompileImageRecognitionAgent(Settings.Current, currentAgent.agentName);
                }
                else
                {
                    currentAgent.agentName = B.tbAgentName2.Text;
                    currentAgent.keys = B.tbKeys.Text;
                    currentAgent.xPath = B.tbXPath.Text;
                    currentAgent.templateUrl = B.tbTemplatesURL.Text;
                    _compileService.CompileTextFinderAgent(currentAgent.templateUrl, currentAgent.xPath,  currentAgent.keys.Split(' '), currentAgent.agentName);
                }
                saveListAgents.Add(currentAgent);
            }

        }
        
        
    }
}
